package com.system.config;

import com.system.config.mybatis.plugins.ExecutorPlugin;
import com.system.config.mybatis.plugins.ResultSetInterceptor;
import com.system.config.mybatis.plugins.page.PageInterceptor;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;
import org.springframework.core.annotation.Order;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.data.transaction.ChainedTransactionManager;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.transaction.annotation.TransactionManagementConfigurer;

import javax.sql.DataSource;
import java.io.IOException;

@EnableTransactionManagement
@Configuration
@Order(4)
public class DBSyncConfig implements TransactionManagementConfigurer {


    /**
     * 两个SqlSessionFactoryBean设置
     **/
    @Bean
    @Qualifier("sourceSqlSessionFactory")
    public SqlSessionFactory sourceSqlSessionFactory(@Autowired @Qualifier("sourceDataSource") DataSource sourceDataSource) {
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        sqlSessionFactoryBean.setDataSource(sourceDataSource);
        org.apache.ibatis.session.Configuration conf = new org.apache.ibatis.session.Configuration();
        conf.setMapUnderscoreToCamelCase(true);
        conf.setLogPrefix("dao");

        sqlSessionFactoryBean.setConfiguration(conf);
        ExecutorPlugin executorPlugin = new ExecutorPlugin();
        ResultSetInterceptor resultSetInterceptor = new ResultSetInterceptor();
        PageInterceptor pageInterceptor = new PageInterceptor();
        Interceptor[] interceptors = new Interceptor[]{executorPlugin ,resultSetInterceptor,pageInterceptor };
        sqlSessionFactoryBean.setPlugins(interceptors);
        PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        try {
            sqlSessionFactoryBean.setMapperLocations(resolver.getResources("classpath:mapper/*.xml"));
        } catch (IOException e1) {
            e1.printStackTrace();
        }
        try {
            return sqlSessionFactoryBean.getObject();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    @Bean
    @Qualifier("targetSqlSessionFactory")
    public SqlSessionFactory targetSqlSessionFactory(@Autowired @Qualifier("targetDataSource") DataSource targetDataSource) {
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        sqlSessionFactoryBean.setDataSource(targetDataSource);
        org.apache.ibatis.session.Configuration conf = new org.apache.ibatis.session.Configuration();
        conf.setMapUnderscoreToCamelCase(true);
        conf.setLogPrefix("dao");
        sqlSessionFactoryBean.setConfiguration(conf);

        PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        try {
            sqlSessionFactoryBean.setMapperLocations(resolver.getResources("classpath:mapper/*.xml"));
        } catch (IOException e1) {
            e1.printStackTrace();
        }
        try {
            return sqlSessionFactoryBean.getObject();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 两个SqlSession 设置
     **/
    @Bean
    @Scope("prototype")
    @Qualifier("sourceSqlSessionTemplate")
    public SqlSessionTemplate sourceSqlSessionTemplate(@Autowired @Qualifier("sourceSqlSessionFactory") SqlSessionFactory sourceSqlSessionFactory) {
        return new SqlSessionTemplate(sourceSqlSessionFactory);

    }

    @Bean
    @Scope("prototype")
    @Qualifier("targetSessionTemplate")
    public SqlSessionTemplate targetSessionTemplate(@Autowired @Qualifier("targetSqlSessionFactory") SqlSessionFactory targetSessionFactory) {
        return new SqlSessionTemplate(targetSessionFactory);
    }

    @Autowired
    @Qualifier("targetDataSource")
    DataSource targetDataSource;
    @Autowired
    @Qualifier("sourceDataSource")
    DataSource sourceDataSource;

    @Override
    public PlatformTransactionManager annotationDrivenTransactionManager() {
        DataSourceTransactionManager dtm1 = new DataSourceTransactionManager(sourceDataSource);
        DataSourceTransactionManager dtm2 = new DataSourceTransactionManager(targetDataSource);
        ChainedTransactionManager ctm = new ChainedTransactionManager(dtm1, dtm2);
        return ctm;
    }

}
